home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-10-06 | 36.4 KB | 1,400 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // SpriteFrame.c
- //
- // Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
- //
- // Description: implementation of the frame stuff
- ///--------------------------------------------------------------------------------------
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __SWCOMMON__
- #include <SWCommonHeaders.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include <SpriteWorldUtils.h>
- #endif
-
- #ifndef __SPRITECOMPILER__
- #include <SpriteCompiler.h>
- #endif
-
- #ifndef __SPRITEFRAME__
- #include <SpriteFrame.h>
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrame(
- GDHandle theGDH,
- FramePtr* newFrameP,
- Rect* frameRect,
- short depth,
- Boolean createGWorld)
- {
- OSErr err = noErr;
- GWorldPtr frameGWorld;
- FramePtr tempFrameP;
- long numScanLines;
-
- SW_ASSERT(theGDH != NULL);
- SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
- frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
-
- *newFrameP = NULL;
-
- numScanLines = frameRect->bottom - frameRect->top;
-
- tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
- (sizeof(unsigned long) * (numScanLines+1)));
-
- if (tempFrameP != NULL)
- {
- // note: frame rect & depth must always be set, even if no frame GWorld exists
- tempFrameP->frameRect = *frameRect;
- tempFrameP->frameDepth = depth;
- tempFrameP->numScanLines = numScanLines;
- SW_SET_RECT(tempFrameP->collisionInset, 0, 0, 0, 0);
- tempFrameP->usesCollisionInset = false;
-
- if ( createGWorld )
- {
- if ( SWGetPixBitDepth((**theGDH).gdPMap) == depth )
- err = NewGWorld( &frameGWorld, depth, frameRect, nil, theGDH, noNewDevice );
- else
- err = NewGWorld( &frameGWorld, depth, frameRect, nil, nil, (GWorldFlags)nil );
-
- if (err == noErr)
- {
- tempFrameP->framePort = frameGWorld;
- tempFrameP->frameDevice = GetGWorldDevice( frameGWorld );
- tempFrameP->framePixHndl = GetGWorldPixMap( frameGWorld );
-
- SWInitializeFrame( tempFrameP );
- }
- }
- else
- {
- tempFrameP->framePort = NULL;
- tempFrameP->frameDevice = NULL;
- tempFrameP->framePixHndl = NULL;
- err = noErr;
- }
-
- if ( err == noErr )
- {
- tempFrameP->hotSpotH = 0;
- tempFrameP->hotSpotV = 0;
- tempFrameP->tileMaskIsSolid = false;
- tempFrameP->sharesGWorld = false;
- tempFrameP->isFrameLocked = false;
- tempFrameP->isWindowFrame = false;
- tempFrameP->interlacingIsOn = false;
- tempFrameP->skipOddLines = true;
-
- tempFrameP->rleDataH = NULL;
- tempFrameP->rleTokenStart = NULL;
- #if SW_68K
- tempFrameP->pixCodeH = NULL;
- tempFrameP->frameBlitterP = NULL;
- #endif
-
- // the useCount keeps track of the number of sprites that
- // are using this frame. we need to know this so we don't
- // dispose this frame twice when we are disposing the
- // sprites that use it.
- tempFrameP->useCount = 0;
-
- *newFrameP = tempFrameP;
- }
-
- }
- else
- {
- err = MemError();
- }
-
- if (err != noErr)
- {
- if (tempFrameP != NULL)
- {
- if (tempFrameP->framePort != NULL)
- DisposeGWorld(tempFrameP->framePort);
- DisposePtr((Ptr)tempFrameP);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateWindowFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateWindowFrame(
- CWindowPtr srcWindowP,
- FramePtr* newFrameP,
- Rect* frameRect,
- short maxHeight)
- {
- OSErr err = noErr;
- FramePtr tempFrameP = NULL;
- long numScanLines;
-
- SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0);
- SW_ASSERT(frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
-
- *newFrameP = NULL;
-
- // more scanlines than we need, but this allows us to
- // make the window larger later without having to dispose
- // and re-create the WindowFrame.
- numScanLines = (srcWindowP->portRect.bottom - srcWindowP->portRect.top);
- numScanLines = SW_MAX(numScanLines, maxHeight);
-
- // Clip frameRect with the window's boundaries
- frameRect->top = SW_MAX(frameRect->top, srcWindowP->portRect.top);
- frameRect->left = SW_MAX(frameRect->left, srcWindowP->portRect.left);
- frameRect->bottom = SW_MIN(frameRect->bottom, srcWindowP->portRect.bottom);
- frameRect->right = SW_MIN(frameRect->right, srcWindowP->portRect.right);
-
- tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
- (sizeof(unsigned long) * numScanLines));
-
- if (tempFrameP != NULL)
- {
- tempFrameP->framePort = srcWindowP;
- tempFrameP->frameDevice = GetMainDevice();
- tempFrameP->framePixHndl = srcWindowP->portPixMap;
- tempFrameP->frameDepth = SWGetPixBitDepth( srcWindowP->portPixMap );
- tempFrameP->frameRect = *frameRect;
- tempFrameP->numScanLines = numScanLines;
- tempFrameP->sharesGWorld = false;
- tempFrameP->isWindowFrame = true;
- tempFrameP->isFrameLocked = false;
- tempFrameP->interlacingIsOn = false;
- tempFrameP->skipOddLines = true;
-
- SWInitializeFrame( tempFrameP );
-
- *newFrameP = tempFrameP;
- }
- else
- {
- err = MemError();
- }
-
- if (err != noErr)
- {
- if (tempFrameP != NULL)
- {
- DisposePtr((Ptr)tempFrameP);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromCicnResource
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrameFromCicnResource(
- SpriteWorldPtr destSpriteWorld,
- FramePtr* newFrameP,
- short iconResID,
- MaskType maskType)
- {
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDH;
- GDHandle theGDH;
- FramePtr tempFrameP;
- CIconHandle cIconH;
- RgnHandle maskRgn;
- Rect frameRect;
-
- *newFrameP = NULL;
- tempFrameP = NULL;
-
- SW_ASSERT(destSpriteWorld != NULL);
-
- GetGWorld(&saveGWorld, &saveGDH);
-
- cIconH = GetCIcon( iconResID );
-
- if (cIconH != NULL)
- {
- HNoPurge((Handle)cIconH);
- frameRect = (**cIconH).iconPMap.bounds;
-
- theGDH = destSpriteWorld->mainSWGDH;
-
- err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorld->pixelDepth, kCreateGWorld);
- }
- else
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
-
- if (err == noErr)
- {
- (void)LockPixels( tempFrameP->framePixHndl );
- SetGWorld(tempFrameP->framePort, nil);
- EraseRect( &frameRect );
- PlotCIcon(&frameRect, cIconH);
- UnlockPixels( tempFrameP->framePixHndl );
-
- // make a region mask
- if ((maskType & kRegionMask) != 0)
- {
- err = SWCreateRegionFromCIconMask(&maskRgn, cIconH);
-
- if (err == noErr)
- {
- SWSetFrameMaskRgn(tempFrameP, maskRgn);
- }
- }
- }
-
- if (err == noErr)
- {
- // make a pixel mask
- if ((maskType & kPixelMask) != 0)
- {
- // This is just like loading a mask PICT for a Sprite created from a PICT.
- err = SWCreateGWorldFromCIconMask(destSpriteWorld, &tempFrameP->maskPort, cIconH);
-
- if (err == noErr)
- {
- tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
- tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
-
- // This fixes the image GWorld so it works properly with 16-bit and 32-bit
- // blitters. Otherwise, a partial-mask blitter would be needed.
- SWFixImageGWorld( tempFrameP->framePort, tempFrameP->maskPort, (RectPtr) NULL );
- }
-
- // Invert the maskPort if in 8-bits or less. (Not necessary if we create the mask
- // using SWCreatePixelMaskFromGWorld.)
- if (err == noErr && destSpriteWorld->pixelDepth <= 8)
- {
- SWInvertGWorld(tempFrameP->maskPort);
- }
- }
- }
-
- if (cIconH != NULL)
- {
- DisposeCIcon(cIconH);
- }
-
- if (err == noErr)
- {
- *newFrameP = tempFrameP;
- }
-
- if (err != noErr)
- {
- // an error occurred so dispose of anything we managed to create
- if (tempFrameP != NULL)
- {
- SWDisposeFrame(&tempFrameP);
- }
- }
-
- SetGWorld(saveGWorld, nil);
-
- SWSetStickyIfError( err );
- return err;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromPictResource - currently only called by SWCreateSpriteFromPictResource.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrameFromPictResource(
- SpriteWorldPtr destSpriteWorldP,
- FramePtr* newFrameP,
- short pictResID,
- short maskResID,
- MaskType maskType)
- {
- OSErr err;
- GWorldPtr saveGWorld,
- tempMaskGWorldP;
- GDHandle saveGDH;
- GDHandle theGDH;
- PicHandle spritePictH;
- FramePtr tempFrameP;
- RgnHandle maskRgn;
- Rect frameRect;
- Boolean needToInvertMask;
-
- SW_ASSERT(destSpriteWorldP != NULL);
-
- tempFrameP = NULL;
- *newFrameP = NULL;
- tempMaskGWorldP = NULL;
- needToInvertMask = true;
-
- GetGWorld(&saveGWorld, &saveGDH);
-
- spritePictH = GetPicture(pictResID);
-
- if (spritePictH != NULL)
- {
- frameRect = (**spritePictH).picFrame;
- OffsetRect( &frameRect, -frameRect.left, -frameRect.top );
-
- theGDH = destSpriteWorldP->mainSWGDH;
-
- err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, destSpriteWorldP->pixelDepth, kCreateGWorld);
-
- if (err == noErr)
- {
- (void)LockPixels( tempFrameP->framePixHndl );
- SetGWorld(tempFrameP->framePort, nil);
- EraseRect(&frameRect); // Necessary for some wierd PICT resource formats, like XOr
- DrawPicture(spritePictH, &frameRect);
- UnlockPixels( tempFrameP->framePixHndl );
- ReleaseResource((Handle)spritePictH);
- }
-
- if ( err == noErr && maskType != kNoMask )
- {
- // Create the GWorld used to hold the mask.
- err = SWCreateGWorldFromPictResource(destSpriteWorldP, &tempMaskGWorldP, maskResID);
-
- if (err == noErr)
- {
- // If this is a self-masking Sprite, create the mask based on the image.
- if ( pictResID == maskResID && tempMaskGWorldP != NULL )
- {
- err = SWCreatePixelMaskFromGWorld( tempFrameP->framePort, tempMaskGWorldP, (RectPtr) NULL );
- needToInvertMask = false;
-
- // If the depth is 8-bits or less, and we need to create a region mask,
- // invert the maskGWorld so the region mask is created correctly.
- if (destSpriteWorldP->pixelDepth <= 8 && (maskType & kRegionMask) != 0 )
- {
- SWInvertGWorld(tempMaskGWorldP);
- needToInvertMask = true;
- }
- }
- else if ( (maskType & kPixelMask) != 0 )
- {
- // For Sprites that are not self-masking and have a pixel mask, we
- // should still fix the GWorld's image, in case SWTransparentColor
- // is not white, or in case the depth is 16-bits or above.
- SWFixImageGWorld( tempFrameP->framePort, tempMaskGWorldP, (RectPtr) NULL );
- }
- }
- }
-
- // make a region mask
- if (((maskType & kRegionMask) != 0) && (err == noErr))
- {
- err = SWCreateRegionFromGWorldAndRect( &maskRgn,
- tempMaskGWorldP, &tempFrameP->frameRect );
-
- if (err == noErr)
- {
- SWSetFrameMaskRgn(tempFrameP, maskRgn);
- }
- }
-
- if (err == noErr)
- {
- // If a pixel mask is wanted, fix the tempMaskGWorld
- // if the depth is 8-bits or less.
- if ((maskType & kPixelMask) != 0)
- {
- if (destSpriteWorldP->pixelDepth <= 8 && needToInvertMask)
- {
- SWInvertGWorld(tempMaskGWorldP);
- }
- } // If no pixel Mask wanted, dispose of the
- else // GWorld we used to make the region mask.
- {
- if (tempMaskGWorldP != NULL)
- {
- DisposeGWorld( tempMaskGWorldP );
- tempMaskGWorldP = NULL;
- }
- }
-
- if ( tempMaskGWorldP != NULL )
- {
- tempFrameP->maskPort = tempMaskGWorldP;
- tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
- tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
- }
- else
- {
- tempFrameP->maskPort = NULL;
- tempFrameP->maskDevice = NULL;
- tempFrameP->maskPixHndl = NULL;
- }
- }
-
- if (err == noErr)
- {
- *newFrameP = tempFrameP;
- }
- else
- {
- // an error occurred so dispose of anything we managed to create
- if (tempFrameP != NULL)
- {
- SWDisposeFrame(&tempFrameP);
- }
- }
- }
- else
- {
- err = MemError();
- if ( err == noErr )
- err = resNotFound;
- }
-
- SetGWorld(saveGWorld, nil);
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromGWorldAndRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrameFromGWorldAndRect(
- FramePtr* newFrameP,
- GWorldPtr pictGWorld,
- GWorldPtr maskGWorld,
- Rect* frameRect,
- MaskType maskType)
- {
- OSErr err;
- GWorldPtr tempMaskGWorld;
-
- err = SWCreateFrameFromGWorldAndRectStart( &tempMaskGWorld,
- frameRect->right - frameRect->left, frameRect->bottom - frameRect->top, maskType );
-
- if ( err == noErr )
- {
- err = SWCreateFrameFromGWorldAndRectPartial( newFrameP, pictGWorld, maskGWorld,
- tempMaskGWorld, frameRect, maskType );
-
- SWCreateFrameFromGWorldAndRectFinish( tempMaskGWorld );
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromGWorldAndRectStart
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrameFromGWorldAndRectStart(
- GWorldPtr *tempMaskGWorld,
- short maxWidth,
- short maxHeight,
- MaskType maskType)
- {
- OSErr err = noErr;
-
- *tempMaskGWorld = NULL;
- if ((maskType & kRegionMask) != 0)
- {
- err = SWCreateRegionFromGWorldAndRectStart( tempMaskGWorld, maxWidth, maxHeight );
- }
- return err;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromGWorldAndRectFinish
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCreateFrameFromGWorldAndRectFinish(
- GWorldPtr tempMaskGWorld)
- {
- SWCreateRegionFromGWorldAndRectFinish( tempMaskGWorld );
- }
-
- ///--------------------------------------------------------------------------------------
- // SWCreateFrameFromGWorldAndRectPartial
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateFrameFromGWorldAndRectPartial(
- FramePtr* newFrameP,
- GWorldPtr pictGWorld,
- GWorldPtr maskGWorld,
- GWorldPtr tempMaskGWorld,
- Rect* frameRect,
- MaskType maskType)
- {
- OSErr err = noErr;
- short depth;
- long numScanLines;
- FramePtr tempFrameP;
- RgnHandle maskRgn;
-
- SW_ASSERT(pictGWorld != NULL);
- SW_ASSERT(frameRect->top >= 0 && frameRect->left >= 0 &&
- frameRect->right > frameRect->left && frameRect->bottom > frameRect->top);
-
- tempFrameP = NULL;
- *newFrameP = NULL;
-
- numScanLines = frameRect->bottom - frameRect->top;
- depth = SWGetPixBitDepth( GetGWorldPixMap(pictGWorld) );
-
- tempFrameP = (FramePtr)NewPtrClear((Size)sizeof(FrameRec) +
- (sizeof(unsigned long) * (numScanLines+1)));
-
- if (tempFrameP != NULL)
- {
- tempFrameP->framePort = pictGWorld;
- tempFrameP->frameDevice = GetGWorldDevice( pictGWorld );
- tempFrameP->framePixHndl = GetGWorldPixMap( pictGWorld );
- tempFrameP->frameDepth = depth;
-
- // make a pixel mask
- if ((maskType & kPixelMask) != 0)
- {
- SW_ASSERT(maskGWorld != NULL);
- tempFrameP->maskPort = maskGWorld;
- tempFrameP->maskDevice = GetGWorldDevice( maskGWorld );
- tempFrameP->maskPixHndl = GetGWorldPixMap( maskGWorld);
- }
-
- tempFrameP->frameRect = *frameRect;
- tempFrameP->sharesGWorld = true;
- tempFrameP->isWindowFrame = false;
- tempFrameP->numScanLines = numScanLines;
-
- // the useCount keeps track of the number of sprites that
- // are using this frame. we need to know this so we don't
- // dispose this frame twice when we are disposing the
- // sprites that use it.
- tempFrameP->useCount = 0;
-
- SWInitializeFrame( tempFrameP );
- }
- else
- {
- err = MemError();
- }
-
- if (err == noErr)
- {
- // make a region mask
- if (((maskType & kRegionMask) != 0) && (err == noErr))
- {
- SW_ASSERT(maskGWorld != NULL);
-
- err = SWCreateRegionFromGWorldAndRectPartial(&maskRgn, maskGWorld,
- tempMaskGWorld, frameRect);
-
- if (err == noErr)
- {
- SWSetFrameMaskRgn(tempFrameP, maskRgn);
- }
- }
-
- if (err == noErr)
- {
- *newFrameP = tempFrameP;
- }
- else
- {
- // an error occurred so dispose of anything we managed to create
-
- if (tempFrameP != NULL)
- {
- SWDisposeFrame(&tempFrameP);
- }
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWDisposeFrame(
- FramePtr *oldFramePP)
- {
- Boolean frameDisposed;
- FramePtr oldFrameP = *oldFramePP;
-
- frameDisposed = false;
- if (oldFrameP != NULL)
- {
- SW_ASSERT( !oldFrameP->isWindowFrame );
-
- // is this frame still in use by another sprite?
- if (oldFrameP->useCount > 1)
- {
- // one less sprite is using it now!
- oldFrameP->useCount--;
- }
- else // no more sprites are using this frame
- {
- frameDisposed = true;
- if (oldFrameP->framePort != NULL)
- {
- if ( !oldFrameP->sharesGWorld )
- DisposeGWorld(oldFrameP->framePort);
- oldFrameP->framePort = NULL;
- oldFrameP->frameDevice = NULL;
- oldFrameP->framePixHndl = NULL;
- }
-
- if (oldFrameP->maskRgn != NULL)
- {
- DisposeRgn(oldFrameP->maskRgn);
- oldFrameP->maskRgn = NULL;
- }
-
- if (oldFrameP->maskPort != NULL)
- {
- if ( !oldFrameP->sharesGWorld )
- DisposeGWorld(oldFrameP->maskPort);
- oldFrameP->maskPort = NULL;
- oldFrameP->maskDevice = NULL;
- oldFrameP->maskPixHndl = NULL;
- }
-
- #if SW_68K
- if (oldFrameP->pixCodeH != NULL)
- {
- DisposeHandle((Handle)oldFrameP->pixCodeH);
- oldFrameP->pixCodeH = NULL;
- oldFrameP->frameBlitterP = NULL;
- }
- #endif
-
- DisposePtr((Ptr)oldFrameP);
- *oldFramePP = NULL; // Change the original pointer to NULL
- }
- }
-
- return frameDisposed;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeWindowFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeWindowFrame(
- FramePtr *oldFramePP)
- {
- FramePtr oldFrameP = *oldFramePP;
-
- if (oldFrameP != NULL)
- {
- SW_ASSERT( oldFrameP->isWindowFrame );
-
- DisposePtr((Ptr)oldFrameP);
- *oldFramePP = NULL; // Change the original pointer to NULL
- }
- }
-
- #pragma mark -
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToFrame(
- FramePtr dstFrameP)
- {
- SW_ASSERT(dstFrameP != NULL);
- SW_ASSERT(dstFrameP->framePort != NULL);
- SW_ASSERT(dstFrameP->isFrameLocked);
-
- SetGWorld( dstFrameP->framePort, dstFrameP->frameDevice );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAlignFrameToWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWAlignFrameToWindow(
- FramePtr dstFrameP,
- FramePtr windowFrameP)
- {
- Rect globalRect;
- GWorldPtr newGWorld;
- GWorldFlags flags;
- Boolean wasLocked;
- GWorldPtr oldGWorld;
- GDHandle oldDevice;
- Boolean wasCurrent;
- OSErr err;
- Boolean redraw = false;
-
- SW_ASSERT(windowFrameP != NULL);
- SW_ASSERT(windowFrameP->isWindowFrame);
- SW_ASSERT(dstFrameP != NULL);
- SW_ASSERT(!dstFrameP->isWindowFrame);
-
- if ( dstFrameP->framePort != NULL &&
- windowFrameP->framePort != NULL &&
- dstFrameP->frameDepth == windowFrameP->frameDepth )
- {
- GetGWorld( &oldGWorld, &oldDevice );
- newGWorld = dstFrameP->framePort;
-
- wasCurrent = (newGWorld == oldGWorld);
- SetPort( (GrafPtr) windowFrameP->framePort);
-
- globalRect = dstFrameP->framePort->portRect;
- LocalToGlobal( &topLeft(globalRect) );
- LocalToGlobal( &botRight(globalRect) );
-
- wasLocked = dstFrameP->isFrameLocked;
- if ( wasLocked )
- SWUnlockFrame( dstFrameP );
-
- flags = UpdateGWorld( &newGWorld, 0, &globalRect,
- (CTabHandle) NULL, (GDHandle) NULL, (GWorldFlags) 0 );
-
- if ( !(flags & gwFlagErr) )
- {
- dstFrameP->framePort = newGWorld;
- dstFrameP->framePixHndl = GetGWorldPixMap( newGWorld );
- dstFrameP->frameDevice = GetGWorldDevice( newGWorld );
-
- SetPort( (GrafPtr) newGWorld);
- SetOrigin(0,0);
-
- // did we have to change anything ?
- if ( flags & (reallocPix | newDepth | newRowBytes) )
- {
- SWInitializeFrame( dstFrameP );
- }
- if ( flags & (reallocPix | newDepth | mapPix) )
- {
- redraw = true;
- }
- }
- else
- err = (QDErr) flags;
-
- if ( wasLocked )
- SWLockFrame( dstFrameP );
-
- if ( wasCurrent )
- SWSetPortToFrame( dstFrameP );
- else
- SetGWorld( oldGWorld, oldDevice );
- }
-
- return redraw;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInitializeFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWInitializeFrame(
- FramePtr tempFrameP )
- {
- long curScanLine;
- long rowOffset;
- short depth;
- PixMapHandle pixmap;
-
- SW_ASSERT(tempFrameP != NULL);
- SW_ASSERT(tempFrameP->framePixHndl != NULL);
- SW_ASSERT(tempFrameP->frameDepth != 0);
-
- // Note: do NOT set the useCount in this function,
- // since it might be called again if we need to change depth/rowbytes for some reason...
-
- pixmap = tempFrameP->framePixHndl;
- depth = tempFrameP->frameDepth;
-
- // cache pixmap info for use by our blitter routine
- tempFrameP->frameRowBytes = SWGetPixRowBytes( pixmap );
-
- // this calculation generates a mask value that we use to
- // long word align the rectangle when we draw the frame.
- // note that the expression "sizeof(long) * kBitsPerByte" gives us
- // the number of bits in a long. <-- that ought to always be 32... --afb
-
- // align on long word (4-byte) boundary:
- tempFrameP->rightAlignFactor = (32 / depth) - 1;
- tempFrameP->leftAlignFactor = ~(tempFrameP->rightAlignFactor);
-
- // calculate amount to leftshift pixels to get bytes (works for depths >= 8)
- tempFrameP->pixelShift = depth >> 4;
-
- // here we set up an array of offsets to the scan lines of
- // this frame. this allows us to address a particular scan line
- // without doing a costly multiply. <-- costly on the 68k, that is --afb
-
- // (array data follows right after the frame struct)
- tempFrameP->scanLinePtrArray = (unsigned long*) (tempFrameP + 1);
-
- rowOffset = (long) tempFrameP->frameRect.top * tempFrameP->frameRowBytes;
- for (curScanLine = 0; curScanLine < tempFrameP->numScanLines; curScanLine++)
- {
- tempFrameP->scanLinePtrArray[curScanLine] = rowOffset;
- rowOffset += tempFrameP->frameRowBytes;
- }
-
- }
-
- ///--------------------------------------------------------------------------------------
- // SWSetFrameMaskRgn
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetFrameMaskRgn(
- FramePtr srcFrameP,
- RgnHandle maskRgn)
- {
- SW_ASSERT(srcFrameP != NULL);
- SW_ASSERT(maskRgn != NULL);
-
- if (maskRgn != NULL)
- {
- srcFrameP->maskRgn = maskRgn;
-
- srcFrameP->offsetPoint.h = (**maskRgn).rgnBBox.left;
- srcFrameP->offsetPoint.v = (**maskRgn).rgnBBox.top;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetFrameHotSpot
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetFrameHotSpot(
- FramePtr srcFrameP,
- short hotSpotH,
- short hotSpotV)
- {
- SW_ASSERT(srcFrameP != NULL);
-
- srcFrameP->hotSpotH = hotSpotH;
- srcFrameP->hotSpotV = hotSpotV;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetFrameCollisionInset
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetFrameCollisionInset(
- FramePtr srcFrameP,
- short leftInset,
- short topInset,
- short rightInset,
- short bottomInset)
- {
- SW_ASSERT(srcFrameP != NULL);
-
- if (leftInset == 0 && topInset == 0 && rightInset == 0 && bottomInset == 0)
- srcFrameP->usesCollisionInset = false;
- else
- srcFrameP->usesCollisionInset = true;
-
- SW_SET_RECT(srcFrameP->collisionInset, leftInset, topInset, rightInset, bottomInset)
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetFrameInterlacingMode
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetFrameInterlacingMode(
- FramePtr dstFrameP,
- Boolean skipEveryOtherLine,
- Boolean skipOddLines)
- {
- SW_ASSERT(dstFrameP != NULL);
-
- dstFrameP->interlacingIsOn = skipEveryOtherLine;
- dstFrameP->skipOddLines = skipOddLines;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyFrame - creates a new Frame and copies oldFrameP into it.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCopyFrame(
- SpriteWorldPtr destSpriteWorldP,
- FramePtr oldFrameP,
- FramePtr *newFrameP,
- Boolean copyMasks)
- {
- OSErr err;
- GWorldPtr saveGWorld;
- GDHandle saveGDH;
- GDHandle theGDH;
- GWorldFlags pixelState;
- short depth;
- FramePtr tempFrameP;
- Rect frameRect;
-
- SW_ASSERT(newFrameP != NULL);
- SW_ASSERT(oldFrameP != NULL);
- SW_ASSERT(oldFrameP->framePort != NULL);
- SW_ASSERT(destSpriteWorldP != NULL);
-
- *newFrameP = NULL;
- tempFrameP = NULL;
- depth = destSpriteWorldP->pixelDepth;
- theGDH = destSpriteWorldP->mainSWGDH;
-
- GetGWorld(&saveGWorld, &saveGDH);
-
- // Get size of new frame
- frameRect = oldFrameP->frameRect;
- OffsetRect(&frameRect, -frameRect.left, -frameRect.top);
-
- // Create the new frame
- err = SWCreateFrame(theGDH, &tempFrameP, &frameRect, depth, kCreateGWorld);
-
- // Copy the image from the old frame into the new frame
- if ( err == noErr )
- {
- pixelState = GetPixelsState( oldFrameP->framePixHndl );
- (void)LockPixels( GetGWorldPixMap(oldFrameP->framePort) );
- (void)LockPixels( GetGWorldPixMap(tempFrameP->framePort) );
- SetGWorld( oldFrameP->framePort, nil ); ForeColor( blackColor ); BackColor( whiteColor );
- SetGWorld( tempFrameP->framePort, nil );
-
- CopyBits ( (BitMap*)*GetGWorldPixMap( oldFrameP->framePort ),
- (BitMap*)*GetGWorldPixMap( tempFrameP->framePort ),
- &oldFrameP->frameRect,
- &frameRect,
- srcCopy,
- nil);
-
- // Restore oldFrameP to its previous locked/unlocked state.
- SetPixelsState( oldFrameP->framePort->portPixMap, pixelState );
-
- // Unlock our tempFrameP.
- UnlockPixels( GetGWorldPixMap(tempFrameP->framePort) );
- }
-
-
- // copy region mask
- if ((oldFrameP->maskRgn != NULL) && (err == noErr))
- {
- tempFrameP->maskRgn = NewRgn();
-
- if (tempFrameP->maskRgn == NULL)
- err = MemError();
- else if (copyMasks)
- CopyRgn(oldFrameP->maskRgn, tempFrameP->maskRgn);
- }
-
- // copy pixel mask
- if ((oldFrameP->maskPort != NULL) && (err == noErr))
- {
- if ( SWGetPixBitDepth((**theGDH).gdPMap) == depth )
- err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, theGDH, noNewDevice );
- else
- err = NewGWorld( &tempFrameP->maskPort, depth, &frameRect, nil, nil, 0 );
-
- // Copy pixel mask from old frame into new frame
- if ((err == noErr) && (copyMasks))
- {
- tempFrameP->maskDevice = GetGWorldDevice( tempFrameP->maskPort );
- tempFrameP->maskPixHndl = GetGWorldPixMap( tempFrameP->maskPort );
-
- pixelState = GetPixelsState( oldFrameP->maskPixHndl );
- (void)LockPixels( oldFrameP->maskPixHndl );
- (void)LockPixels( tempFrameP->maskPixHndl );
- SetGWorld( oldFrameP->maskPort, nil );
- ForeColor( blackColor );
- BackColor( whiteColor );
- SetGWorld( tempFrameP->maskPort, nil );
-
- CopyBits( (BitMap*) *oldFrameP->maskPixHndl,
- (BitMap*) *tempFrameP->maskPixHndl,
- &oldFrameP->frameRect,
- &frameRect,
- srcCopy,
- nil);
-
- // Restore oldFrameP to its previous locked/unlocked state.
- SetPixelsState( oldFrameP->maskPixHndl, pixelState );
-
- // Unlock our tempFrameP.
- UnlockPixels( tempFrameP->maskPixHndl );
- }
- }
-
- if (err == noErr)
- {
- *newFrameP = tempFrameP;
- }
- else
- {
- // an error occurred so dispose of anything we managed to create
- if (tempFrameP != NULL)
- {
- SWDisposeFrame(&tempFrameP);
- }
- }
-
- SetGWorld(saveGWorld, nil);
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateFrameMasks - updates the pixel and region masks of a frame, from the frame image
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWUpdateFrameMasks(
- FramePtr srcFrameP)
- {
- RGBColor oldTransparentColor, myBlackColor;
- Boolean frameWasUnlocked = false;
- short depth;
- OSErr err = noErr;
-
- SW_ASSERT(srcFrameP != NULL);
-
- if (!srcFrameP->isFrameLocked)
- {
- SWLockFrame(srcFrameP);
- frameWasUnlocked = true;
- }
-
- depth = srcFrameP->frameDepth;
-
- // If there is a pixel mask...
- if (srcFrameP->maskPort != NULL)
- {
- SW_ASSERT(srcFrameP->framePort != NULL);
-
- // We must set the transparent color to black before re-creating the mask
- // if we are in 16-bits or above, since the image GWorld will have been "fixed".
- if (depth > 8)
- {
- oldTransparentColor = gSWTransparentColor;
- myBlackColor.red = myBlackColor.green = myBlackColor.blue = 0;
- SWSetTransparentColor(&myBlackColor);
- }
-
- // Recreate the pixel mask
- SWCreatePixelMaskFromGWorld( srcFrameP->framePort, srcFrameP->maskPort, &srcFrameP->frameRect );
-
- if (depth > 8)
- SWSetTransparentColor(&oldTransparentColor);
-
- // Recreate the region mask if there is one.
- if (srcFrameP->maskRgn != NULL)
- {
- DisposeRgn( srcFrameP->maskRgn );
-
- // the pixel mask has inverted colors if in indexed mode
- if (depth <= 8)
- SWInvertRect(srcFrameP->maskPort, &srcFrameP->frameRect);
-
- err = SWCreateRegionFromGWorldAndRect( &srcFrameP->maskRgn,
- srcFrameP->maskPort, &srcFrameP->frameRect );
-
- if (err == noErr)
- SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
-
- if (depth <= 8)
- SWInvertRect(srcFrameP->maskPort, &srcFrameP->frameRect);
- }
- }
- else if (srcFrameP->maskRgn != NULL)
- {
- // In case there is a region mask but no pixel mask...
- err = SWCreateRegionMaskFromGWorld( srcFrameP->framePort,
- &srcFrameP->frameRect, srcFrameP->maskRgn );
-
- if (err == noErr)
- SWSetFrameMaskRgn(srcFrameP, srcFrameP->maskRgn);
- }
-
- // if (srcFrameP->rleDataH != NULL && srcFrameP->framePort != NULL)
- // Looks like we can't re-create RLE data for a single frame.
-
- #if SW_68K
- if (srcFrameP->pixCodeH != NULL)
- SWCompileFrame(srcFrameP);
- #endif
-
- if (frameWasUnlocked)
- SWUnlockFrame(srcFrameP);
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockFrame(
- FramePtr srcFrameP)
- {
- PixMapHandle pixMapH;
- long offsetX,offsetY;
-
- SW_ASSERT(srcFrameP != NULL);
- SW_ASSERT(!srcFrameP->isWindowFrame);
-
- if (!srcFrameP->isFrameLocked)
- {
- srcFrameP->isFrameLocked = true;
-
- if (srcFrameP->framePort != NULL)
- {
- SW_ASSERT(srcFrameP->framePixHndl != NULL);
-
- pixMapH = srcFrameP->framePixHndl;
- (void)LockPixels( pixMapH );
- HLockHi( (Handle)pixMapH );
- srcFrameP->framePix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
-
- srcFrameP->frameBaseAddr = SWGetPixBaseAddr( pixMapH );
- srcFrameP->frameRowBytes = SWGetPixRowBytes( pixMapH );
- srcFrameP->frameDepth = SWGetPixBitDepth( pixMapH );
-
- offsetX = - (**pixMapH).bounds.left;
- offsetY = - (**pixMapH).bounds.top;
-
- // calculate start of pixmap
- if ( offsetX != 0 || offsetY != 0 )
- {
- srcFrameP->frameBaseAddr += offsetY * srcFrameP->frameRowBytes;
- srcFrameP->frameBaseAddr += (offsetX * srcFrameP->frameDepth) >> 3;
- }
-
- // calculate pixel offset, in case a pixel is less than a whole byte
- if ( srcFrameP->frameDepth < 8 )
- {
- short pixelStart;
- short roundOff;
-
- // note: don't forget the pixmap bounds here, in case it's been justified for alignment
- pixelStart = -(**pixMapH).bounds.left;
- roundOff = 8 / srcFrameP->frameDepth;
-
- srcFrameP->worldRectOffset = pixelStart % roundOff;
- }
- else
- srcFrameP->worldRectOffset = 0;
-
- }
-
- if (srcFrameP->maskPort != NULL)
- {
- SW_ASSERT(srcFrameP->maskPixHndl != NULL);
-
- pixMapH = srcFrameP->maskPixHndl;
- (void)LockPixels( pixMapH );
- HLockHi( (Handle)pixMapH );
- srcFrameP->maskPix = (PixMapPtr)StripAddress( *(Handle)pixMapH );
-
- srcFrameP->maskBaseAddr = SWGetPixBaseAddr( pixMapH );
-
- // assume mask has bounds w. topLeft(0,0) since we never align frames with masks ?
- }
-
- #if SW_68K
- if (srcFrameP->pixCodeH != NULL)
- {
- HLockHi((Handle)srcFrameP->pixCodeH);
- srcFrameP->frameBlitterP = (CompiledPtr) StripAddress( *(Handle)srcFrameP->pixCodeH );
- }
- #endif
-
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockFrame(
- FramePtr srcFrameP)
- {
- SW_ASSERT(srcFrameP != NULL);
- SW_ASSERT(!srcFrameP->isWindowFrame);
-
- if (srcFrameP->isFrameLocked)
- {
- srcFrameP->isFrameLocked = false;
-
- if (srcFrameP->framePort != NULL && srcFrameP->framePixHndl != NULL)
- {
- HUnlock( (Handle)srcFrameP->framePixHndl );
- UnlockPixels(srcFrameP->framePixHndl);
- }
-
- srcFrameP->framePix = NULL;
- srcFrameP->frameBaseAddr = NULL;
-
- if (srcFrameP->maskPort != NULL && srcFrameP->maskPixHndl != NULL)
- {
- HUnlock( (Handle)srcFrameP->maskPixHndl );
- UnlockPixels(srcFrameP->maskPixHndl);
- }
-
- srcFrameP->maskPix = NULL;
- srcFrameP->maskBaseAddr = NULL;
-
- #if SW_68K
- if (srcFrameP->pixCodeH != NULL)
- {
- HUnlock((Handle)srcFrameP->pixCodeH);
- srcFrameP->frameBlitterP = NULL;
- }
- #endif
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockWindowFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockWindowFrame(
- FramePtr windowFrameP)
- {
- GrafPtr savePort;
- Rect globalRect;
- PixMapHandle pixMapH;
- GDHandle maxDevice;
- long offsetX,offsetY;
-
- SW_ASSERT(windowFrameP != NULL);
- SW_ASSERT(windowFrameP->framePort != NULL);
- SW_ASSERT(windowFrameP->framePixHndl != NULL);
- SW_ASSERT(windowFrameP->isWindowFrame);
-
- if (!windowFrameP->isFrameLocked)
- {
- windowFrameP->isFrameLocked = true;
- pixMapH = windowFrameP->framePixHndl;
- HLockHi( (Handle)pixMapH );
- windowFrameP->framePix = (PixMapPtr)StripAddress( *pixMapH );
-
- // note: windowFrameP->frameDevice is ALWAYS MainDevice !
- // windowFrameP->framePixHndl is ALWAYS a PixMap on MainDevice (but with different bounds)
- // (so neither of those will help us to get address for blitter... )
-
- // get global frame rect
- GetPort( &savePort );
- SetPort( (GrafPtr) windowFrameP->framePort );
- globalRect = windowFrameP->framePort->portRect;
- LocalToGlobal(&topLeft(globalRect));
- LocalToGlobal(&botRight(globalRect));
- SetPort( savePort );
-
- // determine which device to use (deepest intersecting)
- maxDevice = GetMaxDevice( &globalRect );
- pixMapH = (**maxDevice).gdPMap;
-
- windowFrameP->frameBaseAddr = SWGetPixBaseAddr( pixMapH );
- windowFrameP->frameRowBytes = SWGetPixRowBytes( pixMapH );
- windowFrameP->frameDepth = SWGetPixBitDepth( pixMapH );
-
- // calculate start of window on device
- offsetX = globalRect.left - (**maxDevice).gdRect.left;
- offsetY = globalRect.top - (**maxDevice).gdRect.top;
-
- // calculate start of pixmap bounds
- offsetX -= (**pixMapH).bounds.left;
- offsetY -= (**pixMapH).bounds.top;
-
- if ( offsetX != 0 || offsetY != 0 )
- {
- windowFrameP->frameBaseAddr += offsetY * windowFrameP->frameRowBytes;
- windowFrameP->frameBaseAddr += (offsetX * windowFrameP->frameDepth) >> 3;
- }
-
- // calculate pixel offset, in case a pixel is less than a whole byte
- if ( windowFrameP->frameDepth < 8 )
- {
- short pixelStart;
- short roundOff;
-
- pixelStart = offsetX;
- roundOff = 8 / windowFrameP->frameDepth;
-
- windowFrameP->worldRectOffset = pixelStart % roundOff;
- }
- else
- windowFrameP->worldRectOffset = 0;
-
- SWInitializeFrame(windowFrameP);
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockWindowFrame
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockWindowFrame(
- FramePtr windowFrameP)
- {
- SW_ASSERT(windowFrameP != NULL);
- SW_ASSERT(windowFrameP->isWindowFrame);
-
- if (windowFrameP->isFrameLocked)
- {
- windowFrameP->isFrameLocked = false;
- HUnlock( (Handle)windowFrameP->framePixHndl );
- windowFrameP->framePix = NULL;
- windowFrameP->frameBaseAddr = NULL;
- }
- }
-
-